<!--
Date: 2025-08-13
Copyright (c) 2025 Industrial Software Feature Database
-->
<template>
  <div class="upload_elements">
    <div class="steps">
      <el-steps :active="active" style="width: 100%" align-center>
        <el-step title="文件上传" />
        <!-- <el-step title="压缩包文件解析" /> -->
        <el-step title="上传数据规则检验" />
        <el-step title="数据更正" />
        <el-step title="导入完成" />
      </el-steps>
    </div>
    <div class="upload" v-show="active === 1" v-loading="uploadLoading" element-loading-text="压缩包解压中...">
      <div class="upload_content">
        <el-form size="small" label-width="120">
          <el-form-item label="机型：" required>
            <el-select style="width: 400px" v-model="uploadForm.structureModelId" clearable placeholder="请选择机型" @change="modelChange">
              <el-option v-for="item in modelNumberList" :label="item.name" :value="item.mark" :key="item.mark"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="批次号：" required>
            <el-select style="width: 400px" v-model="uploadForm.batchNumber" clearable placeholder="请选择批次号" @change="batchChange">
              <el-option v-for="item in batchList" :label="item.name" :value="item.mark" :key="item.mark"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-if="props.pageType === 'importComp'" label="部段：" required>
            <el-select style="width: 400px" v-model="uploadForm.sectionNumber" clearable placeholder="请选择部段号">
              <el-option v-for="item in sectionList" :label="item.name + '[' + item.mark + ']'" :value="item.mark" :key="item.mark"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-if="props.pageType !== 'importComp'" label="索引文件名：" >
            <el-input style="width: 400px" v-model="uploadForm.indexFileName" placeholder="请输入索引文件名，如：C919_10002_D20200910"/>
          </el-form-item>
          <el-form-item label="上传文件：" required>
            <el-upload class="upload-demo" style="width:400px;height:150px;" drag :file-list="uploadFiles" :beforeUpload="beforeUpload" :http-request="componentImport">
              <el-icon class="el-icon--upload"><upload-filled /></el-icon>
              <div class="el-upload__text">点击或将文件拖拽到这里上传，支持压缩包格式：.ZIP、.RAR，每次只支持一个压缩包上传，大小限制500M。</div>
            </el-upload>
          </el-form-item>
        </el-form>
      </div>
    </div>
    <div class="upload_check" v-show="active === 2">
      <CheckResult v-if="active === 2 && !dialogFormVisible" :checkTotal="checkTotal" :notExistsList="notExistsList" :versionNotSameList="versionNotSameList" :dataNotSameList="dataNotSameList" />
    </div>
    <div class="upload_list" v-show="active === 3" v-loading="uploadLoading" element-loading-text="数据导入中...">
      <FileTree :batchNumber="uploadForm.batchNumber" :data="zipData" v-if="active === 3" :active="active" @change="dataChange" />
    </div>
    <div class="upload_success" v-show="active === 4">
      <div class="upload_success_message">
        <el-icon size="48" color="#67C23A"><CircleCheck /></el-icon>
        <div>
          本次成功导入数据 <span style="color: #02790e">{{ importNumber }}</span> 条，修改后导入的数据
          <span style="color: #f59a23">{{ updatedImportNumber }}</span> 条；未导入的数据 <span style="color: red">{{ notImportNumber }}</span> 条。
        </div>
      </div>
      <FileTree :data="importedData" v-if="active === 4" :active="active" />
    </div>
    <div class="option_btn" v-if="!dialogFormVisible">
      <el-button size="small" type="primary" :disabled="uploadLoading" v-show="active === 1" @click="step('next', 2)">下一步</el-button>
      <el-button size="small" type="primary" @click="exportExcel" v-show="active === 2">导出数据</el-button>
      <el-button size="small" :disabled="uploadLoading" v-show="active === 2" @click="step('pre', 1)">返回上一步</el-button>
      <el-button size="small" type="primary" :disabled="uploadLoading" v-show="active === 2" @click="step('next', 3)">{{btnName}}</el-button>
      <el-button size="small" type="primary" :disabled="uploadLoading" v-show="active === 3" @click="comfirmImport">确认导入</el-button>
      <el-button size="small" :disabled="uploadLoading" v-show="active === 3" @click="step('pre', 2)">上一步</el-button>
      <el-button size="small" type="primary" v-show="active === 4" @click="finish">完成</el-button>
      <el-button size="small" v-show="active !== 4" @click="cancel" :disabled="uploadLoading">取消</el-button>
    </div>
    <el-dialog class="load-cover-dialog" v-model="coverFlag" :show-close="false" width="680">
      <div v-loading="uploadLoading" element-loading-text="正在导入数据...">
        <div class="cover-header">
          <el-icon :size="30" color="#e6a23c">
            <Warning />
          </el-icon>
          <h3>请确认是否进行整机覆盖导入</h3>
        </div>
        <div style="margin-left: 30px;">选择整机覆盖导入后，系统将利用本次数据对原机型批次下的历史数据进行覆盖，请谨慎操作！</div>
        <div style="margin: 10px 0 0 30px;">
          <el-link type="success" @click="conformCoverOrNot('N')">一般导入</el-link>
          <el-divider direction="vertical" />
          <el-link type="primary" @click="conformCoverOrNot('Y')">覆盖导入</el-link>
          <el-divider direction="vertical" />
          <el-link type="info" @click="coverFlag = false">取消</el-link>
        </div>
      </div>
    </el-dialog>
  </div>
  <el-dialog v-model="dialogFormVisible" title="正在对数据进行规则检测" width="500" @close="cancelLoadFile">
    <el-table v-loading="dialogFormVisible" :data="[]" style="width: 100%">
    </el-table>
    <p style="text-align: center;">请耐心等待，正在对数据进行规则检测。</p>
  </el-dialog>
</template>
<script  setup name="UploadElements">
import * as XLSX from 'xlsx';
import { preImport, getStructureTreeList, zipImport, cancelImport, getModelBatchNoList, importComponent } from '@/api/elementsLibrary/index';
import FileTree from './FileTree.vue';
import CheckResult from './CheckResult.vue';
import axios from 'axios';
import { getToken } from '@/utils/auth';
import { modelAboveRefAndFunc } from './common.js';
const { modelNumberList, batchList, sectionList, getStructureList, modelChangeFunc, batchChangeFunc } = modelAboveRefAndFunc();
const props = defineProps(['pageType']);
const emit = defineEmits(['handleEvent']);
const active = ref(1);
// 上传进度条展示
const loadPercentage = ref(0);
const source = ref(null);
const dialogFormVisible = ref(false);
const uploadFiles = ref([]);
// 检测结果集
const versionNotSameList = ref([]); // 零件版本不一致
const dataNotSameList = ref([]); // 数据不一致
const notExistsList = ref([]); // 零件不存在
const checkTotal = ref(0); // 检测总数
// 文件解析loading
const uploadLoading = ref(false);
// zip上传form表单
const uploadForm = ref({ structureModelId: '' ,indexFileName:'', batchNumber: '', sectionNumber: '' });
// 机型下拉列表
const structureModel = ref([]);
// 批次下拉列表
const batchNumberList = ref([]);
// zip包平铺数据
const zipData = ref([]);
// 导入后数据
const importedData = ref([]);
// 成功导入条数
const importNumber = ref(0);
// 修改后导入条数
const updatedImportNumber = ref(0);
//未导入条数
const notImportNumber = ref(0);
// 已修改的数据集合
const modifyDataIds = ref([]);
const btnName = ref('下一步')
// 是否整机覆盖
const isCover = ref('Y');
const coverFlag = ref(false);
// 验证文件格式是否正确
const beforeUpload = (file) => {
  let isFile = file.name.split('.')[file.name.split('.').length - 1] == 'zip' || file.name.split('.')[file.name.split('.').length - 1] == 'rar';
  const isLt = file.size / 1024 / 1024 < 500;
  if (!isFile) {
    ElMessage.error('导入文件格式不正确');
    return false;
  }
  if (!isLt) {
    ElMessage.error(`导入文件太大，请交由系统管理员进行处理`);
    return false;
  }
  //清空filelist
  uploadFiles.value = [];
  return isFile;
};
// 读取压缩文件
const componentImport = async (file) => {
  uploadFiles.value.push(file.file);
};
const dataChange = (data) => {
  zipData.value = data.changeData;
  modifyDataIds.value = data?.modifyDataIds;
};

// 导出数据
const exportExcel = () => {
  const fileTypeMap = {
    'part': '零件',
    'fastener': '紧固件'
  }
  const data1 = [
    ["序号", "编号", "类型", "版本号", "所属组件", "所属部段", "所属机型"]
  ];
  const data2 = [
    ["序号", "编号", "类型", "所属组件", "所属部段", "所属机型", "导入零组件的版本号", "对应原始装机清单的版本号"]
  ];
  const data3 = [
    ["序号", "编号", "类型", "版本号", "所属组件", "所属部段", "所属机型", "导入零件的数量", "对应原始装机清单的零件数量"]  
  ];
  if (notExistsList.value.length > 0) {
    notExistsList.value.forEach((item, index) => {
      const { partNumber, fileType, versionNumber, componentNumber, sectionNumber, modelNumber } = item;
      data1.push([index + 1, partNumber, fileTypeMap[fileType], versionNumber, componentNumber, sectionNumber, modelNumber])
    })
  }
  if (versionNotSameList.value.length > 0) {
    versionNotSameList.value.forEach((item, index) => {
      const { partNumber, fileType, componentNumber, sectionNumber, modelNumber, versionNumber, originalVersion } = item;
      data2.push([index + 1, partNumber, fileTypeMap[fileType], componentNumber, sectionNumber, modelNumber, versionNumber, originalVersion])
    })
  }
  if (dataNotSameList.value.length > 0) {
    dataNotSameList.value.forEach((item, index) => {
      const { partNumber, fileType, versionNumber, componentNumber, sectionNumber, modelNumber, importCount, originalImportCount } = item;
      data3.push([index + 1, partNumber, fileTypeMap[fileType], versionNumber, componentNumber, sectionNumber, modelNumber, importCount, originalImportCount])
    })
  }
  
  // 创建工作簿和工作表
  const wb = XLSX.utils.book_new();
  const ws1 = XLSX.utils.aoa_to_sheet(data1);
  const ws2 = XLSX.utils.aoa_to_sheet(data2);
  const ws3 = XLSX.utils.aoa_to_sheet(data3);

  XLSX.utils.book_append_sheet(wb, ws1, "不存在的零件");
  XLSX.utils.book_append_sheet(wb, ws2, "零件版本不一致的情况");
  XLSX.utils.book_append_sheet(wb, ws3, "零件数量不一致的情况");

  // 生成Excel文件并导出
  XLSX.writeFile(wb, "数据检测结果.xlsx");    
}
// 选择是否整机覆盖
const conformCoverOrNot = (isCover) => {
  //调用导入接口
  uploadLoading.value = true;
  let requestApi = props.pageType === 'importComp' ? importComponent(zipData.value) : zipImport({
    boList: zipData.value,
    isCover,
  })
  requestApi
    .then((res) => {
      if (res) {
        importedData.value = res?.data?.partVoList;
        importNumber.value = res?.data?.importNumber;
        updatedImportNumber.value = res?.data?.updatedImportNumber;
        notImportNumber.value = res?.data?.notImportNumber;
        active.value++;
      }
      uploadLoading.value = false;
      coverFlag.value = false;
    })
    .catch(() => {
      uploadLoading.value = false;
      coverFlag.value = false;
      ElMessage({ showClose: true, message: '导入数据失败', type: 'error' });
    });
}
// 确认导入
const comfirmImport = () => {
  if (props.pageType === 'importAll') {
    coverFlag.value = true;
  } else {
    conformCoverOrNot('')
  }
};
const cancelLoadFile = () => {
  source.value.cancel('Operation canceled by the user.');
  dialogFormVisible.value = false;
  active.value = 1;
}
// zip文件解析
const uploadZipFile = () => {
  // 提交校验
  if (!uploadForm.value.structureModelId) {
    ElMessage({ showClose: true, message: '请选择机型！', type: 'error' });
    return;
  }
  if (!uploadForm.value.batchNumber) {
    ElMessage({ showClose: true, message: '请选择批次！', type: 'error' });
    return;
  }
  if (!uploadForm.value.sectionNumber && props.pageType === 'importComp') {
    ElMessage({ showClose: true, message: '请选择部段！', type: 'error' });
    return;
  }
  if (uploadFiles.value.length === 0) {
    ElMessage({ showClose: true, message: '请上传文件！', type: 'error' });
    return;
  }
  const formData = new FormData();
  formData.append('file', uploadFiles.value[0]);
  formData.append('modelNumber', uploadForm.value.structureModelId);
  formData.append('indexFileName', uploadForm.value.indexFileName);
  formData.append('batchNumber', uploadForm.value.batchNumber);
  if (props.pageType === 'importComp') {
    formData.append('sectionNumber', uploadForm.value.sectionNumber);
  }
  // uploadLoading.value = true;
  // active.value = 2;
  dialogFormVisible.value = true;
  // preImport(formData)
  //   .then((res) => {
  //     zipData.value = res?.data;
  //     if (res?.data.length === 0) {
  //       ElMessage({ showClose: true, message: '文件解析失败！', type: 'error' });
  //       return;
  //     }
  //     active.value++;
  //   })
  //   .finally(() => {
  //     uploadLoading.value = false;
  //   });
  const CancelToken = axios.CancelToken;
  source.value = CancelToken.source();
  let VITE_APP_BASE_API = '/dev-api';
  if (import.meta.env.MODE === 'production') {
    VITE_APP_BASE_API = '/prod-api';
  }
  if (import.meta.env.MODE === 'green') {
    VITE_APP_BASE_API = '/isfd-api';
  }
  let requestUrl = props.pageType === 'importComp' ? `${VITE_APP_BASE_API}/isfd/modelManagementPart/component/check/import` : `${VITE_APP_BASE_API}/isfd/modelManagementPart/check/import`;
      axios
        .post(requestUrl, formData, {
          headers: { 'Content-Type': 'multipart/form-data', 'Authorization': 'Bearer ' + getToken() },
          cancelToken: source.value.token,
          onUploadProgress: progressEvent => {
            // 获取已上传的字节数
            const { loaded } = progressEvent;
            // 获取总字节数
            const { total } = progressEvent;
            // 计算百分比进度
            const percentCompleted = Math.round((loaded / total) * 100);
            
            // 展示百分比进度
            console.log(`上传进度: ${percentCompleted}%`, );
            if (percentCompleted === 100) {
              loadPercentage.value = 99;
              // dialogFormVisible.value = false;
            }
            loadPercentage.value = percentCompleted;
          }
        })
        .then((res) => {
          console.log(`上传进度:`, res);
          if (res.data.code == 200) {
            loadPercentage.value = 100;
            dialogFormVisible.value = false;
            let checkPartAll = res.data.data.filter(item => item.fileType == 'part' || item.fileType == 'fastener');
            checkTotal.value = checkPartAll.length;
            versionNotSameList.value = checkPartAll.filter(item => item.exitCheck == 1 && item.versionCheck == 0);
            dataNotSameList.value = checkPartAll.filter(item =>  item.exitCheck == 1 && item.countCheck == 0);
            notExistsList.value = checkPartAll.filter(item => item.exitCheck == 0);
            if (versionNotSameList.value.length > 0 || dataNotSameList.value.length > 0 || notExistsList.value.length > 0) {
              btnName.value = '忽略上述警告并进入下一步';
            } else {
              btnName.value = '下一步';
            }
            zipData.value = res?.data?.data;
            nextTick(() => {
              active.value = 2;
            })
          } else {
            dialogFormVisible.value = false;
            ElMessage({ showClose: true, message: res.data.msg, type: 'error' });
          }
          
        }).catch(function (thrown) {
          if (axios.isCancel(thrown)) {
            console.log('Request canceled', thrown.message);
          } else {
            // 处理错误
          }
        });
};
// 查询机型列表
const getStructureList1 = () => {
  getStructureTreeList({ parentId: 0 }).then((res) => {
    if (res) {
      structureModel.value = res.rows;
    }
  });
};
// 查询批次列表
const getBatchNumberList = () => {
  if (uploadForm.value.structureModelId) {
    uploadForm.value.batchNumber = '';
    batchNumberList.value = [];
    getModelBatchNoList({ modelNumber: uploadForm.value.structureModelId }).then((res) => {
      if (res) {      
        batchNumberList.value = res.data;
      }
    });
  }
};
const modelChange = (e) => {
  uploadForm.value.batchNumber = '';
  uploadForm.value.sectionNumber = '';
  batchList.value = [];
  sectionList.value = [];
  modelChangeFunc(e)
}
const batchChange = (e) => {
  uploadForm.value.sectionNumber = '';
  sectionList.value = [];
  batchChangeFunc(e)
}
// 完成
const finish = () => {
  emit('handleEvent', { component: 'UploadElements', type: 'finish' });
};
// 上一步  下一步
const step = (type, step) => {
  if (type === 'next') {
    if (active.value === 1) {
      // 文件解析
      uploadZipFile();
    } else {
      active.value = step;
    }
  } else {
    active.value--;
  }
};
//取消
const cancel = () => {
  if (modifyDataIds.value.length > 0) {
    // 调用取消接口
    cancelImport(modifyDataIds.value).then((res) => {
      console.log('cancel');
    });
  }
  emit('handleEvent', { component: 'UploadElements', type: 'cancel' });
};
onMounted(() => {
  getStructureList();
});
</script>
  <style lang="scss" scoped>
.upload_elements {
  padding: 10px;
  width: 100%;
  height: calc(100vh - 84px);
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow: scroll;
  .steps {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top:30px;
  }
  .upload {
    width: 600px;
    margin-top: 20px;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 450px;
    .upload_content {
      width: 600px;
      // min-height: calc(100vh - 251px);
      // overflow: auto;
    }
  }
  .upload_check {
    width: 100%;
    padding: 0 50px;
  }
  .upload_list,
  .upload_success {
    margin-top: 10px;
    overflow: hidden;
    min-height: calc(100vh - 251px);
    width: 100%;
  }
  .option_btn {
    margin-top: 20px;
  }
  .upload_success {
    margin-top: 10px;
    .upload_success_message {
      margin-bottom: 10px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }
  }
  :deep(.el-step__title) {
    font-size: 12px;
  }
}
.cover-header {
  display: flex;
  align-items: center;
  h3 {
    margin-left: 10px;
  }
}
:deep(.load-cover-dialog .el-dialog__header) {
  display: none;
}
:deep(.load-cover-dialog .el-dialog__body) {
  border: 1px solid #e6a23c;
  border-radius: 5px;
  background: #e6a23c24;
}
</style>